package icu.twtool.ui.router.routes.exercise

import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import icu.twtool.database.mapper.ExerciseMeteDataMapper
import icu.twtool.database.mapper.PracticeRecordMapper
import icu.twtool.database.model.ExerciseMetaData
import icu.twtool.entity.Exercise
import icu.twtool.ui.component.ConfirmDialog
import icu.twtool.ui.component.ErrorTextButton
import icu.twtool.ui.component.InfoTextButton
import icu.twtool.ui.component.Table
import icu.twtool.ui.component.TableProps
import icu.twtool.ui.component.TertiaryTextButton
import icu.twtool.ui.dialog.PracticeDialog
import icu.twtool.ui.router.routes.practiceRecordManageRoute
import icu.twtool.ui.style.MyColors
import icu.twtool.util.LocalRouteState
import icu.twtool.util.PathUtil
import java.io.ByteArrayOutputStream
import java.io.PrintStream
import kotlin.io.path.outputStream

/**
 * 习题表格
 * @author Wen
 * @since 2022-11-02
 */
@Composable
@Suppress("FunctionName")
fun ExerciseTable(data: List<ExerciseMetaData>, onRefresh: () -> Unit) {
    var deleteDialogData by remember { mutableStateOf<ExerciseMetaData?>(null) }
    var lookExerciseDialogData by remember { mutableStateOf<ExerciseMetaData?>(null) }
    var practiceExerciseDialogData by remember { mutableStateOf<ExerciseMetaData?>(null) }
    Table(
        data,
        arrayOf(
            TableProps("序号", { Modifier.width(96.dp).fillMaxHeight() }) { Text(it.id.toString()) },
            TableProps("习题名", { Modifier.weight(1f).fillMaxHeight() }) { Text(it.name) },
            TableProps("习题类型", { Modifier.width(128.dp).fillMaxHeight() }) { Text(it.type) },
            TableProps("算式数", { Modifier.width(96.dp).fillMaxHeight() }) { Text(it.count.toString()) },
            TableProps("操作", { Modifier.width(200.dp).fillMaxHeight() }) {
                TertiaryTextButton("练习") {
                    practiceExerciseDialogData = it
                }
                InfoTextButton("查看") {
                    lookExerciseDialogData = it
                }
                ErrorTextButton("删除") {
                    deleteDialogData = it
                }
            }
        )
    )
    deleteDialogData?.let {
        val count = PracticeRecordMapper.countByExerciseId(it.id)
        ConfirmDialog("确定删除？", "删除习题或同时删除改习题的所有练习记录，共 $count 条", onCloseRequest = { deleteDialogData = null }) {
            if (ExerciseMeteDataMapper.deleteById(it.id)) {
                onRefresh()
                deleteDialogData = null
            }
        }
    }
    lookExerciseDialogData?.let {
        LookExerciseDialog(it.reallyName) {
            lookExerciseDialogData = null
        }
    }
    practiceExerciseDialogData?.let {
        val exercise = try {
            Exercise.readFile(PathUtil.exercise().resolve(it.reallyName))
        } catch (e: Exception) {
            null
        }
        if (exercise == null) {
            ConfirmDialog("文件损坏", "是否删除习题？", onCloseRequest = { practiceExerciseDialogData = null }) {
                if (ExerciseMeteDataMapper.deleteById(it.id)) {
                    onRefresh()
                }
            }
        } else {
            val routeState = LocalRouteState.current
            PracticeDialog(exercise) { practiceState ->
                PracticeRecordMapper.insert(it.id, practiceState.rightCount, practiceState.practice.name)
                val stream = PrintStream(PathUtil.practice().resolve(practiceState.practice.name).outputStream())
                practiceState.practice.write(out = stream)
                stream.close()
                practiceExerciseDialogData = null
                routeState.active = practiceRecordManageRoute
            }
        }
    }
}

/**
 * 查看练习弹窗
 */
@Composable
@Suppress("FunctionName")
fun LookExerciseDialog(reallyName: String, onCloseRequest: () -> Unit) {
    Dialog(onCloseRequest, title = "习题详情") {
        val listState = rememberLazyListState()
        Surface(
            Modifier.fillMaxSize(),
            color = MyColors.SecondaryBackground,
            contentColor = MyColors.OnSecondaryBackground
        ) {
            LazyColumn(Modifier.fillMaxSize(), listState) {
                item {
                    LazyRow {
                        item {
                            Text(
                                try {
                                    val reallyContent = ByteArrayOutputStream()
                                    val stream = PrintStream(reallyContent)
                                    val file = Exercise.readFile(PathUtil.exercise().resolve(reallyName))
                                    file.write(out = stream)
                                    stream.flush()
                                    val content = reallyContent.toString()
                                    stream.close()
                                    content
                                } catch (e: Exception) {
                                    "文件损坏"
                                }, overflow = TextOverflow.Visible, fontFamily = FontFamily.Monospace, softWrap = false
                            )
                        }
                    }
                }
            }
        }
    }
}